import { animate, state, style, transition, trigger, AnimationEvent } from '@angular/animations';
import { DOCUMENT } from '@angular/common';
import { Component, ElementRef, Inject, OnInit, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { select, Store } from '@ngrx/store';
import { NzModalService } from 'ng-zorro-antd/modal';
import { NzToolTipComponent, NzTooltipDirective } from 'ng-zorro-antd/tooltip';
import { Subscription, timer } from 'rxjs';
import { Song } from 'src/app/services/data-types/common.types';
import { AppStoreModule } from 'src/app/store';
import { SetCurrentAction, SetCurrentIndex, SetPlayList, SetPlayMode, SetSongList } from 'src/app/store/actions/player.actions';
import { BatchActionsService } from 'src/app/store/batch-actions.service';
import { CurrentActions } from 'src/app/store/reducers/player.reducer';
import { getCurrentAction, getCurrentIndex, getCurrentSong, getPlayer, getPlayList, getPlayMode, getSongList } from 'src/app/store/selectors/player.selector';
import { findIndex, shuffle } from 'src/app/utils/array';
import { PlayMode } from './player-type';
import { WyPlayerPanelComponent } from './wy-player-panel/wy-player-panel.component';

const momdeTypes:PlayMode[]=[
  {
    type:'loop',
    laber: "循环"
  },
  {
    type: 'random',
    laber: '随机'
  },
  {
    type: "singleLoop",
    laber: "单曲循环"
  },
]

enum TipTitles{
  Add = "已添加到列表",
  Play = "已开始播放"
}
@Component({
  selector: 'app-wy-player',
  templateUrl: './wy-player.component.html',
  styleUrls: ['./wy-player.component.less'],
  animations: [ trigger('showHide',[
    state('show', style({bottom: 0})),
    state('hide', style({bottom: -71})),
    transition('show=>hide', [animate('0.3s')]),
    transition('hide=>show', [animate('0.1s')]),
  ]) ]
})
export class WyPlayerComponent implements OnInit {
  showPlayer = 'hide';
  isLocked = false;

  controlTooltip = {
    title: "",
    show: false
  }
   //是否正在动画
  animating = false;

  percent = 0;
  bufferPercent = 0;

  songList!: Song[];
  playList!: Song[];
  currentSong!: Song;
  currentIndex!: number;

  duration!:number;
  currentTime!:number;


  // 播放状态
  playing:boolean = false;

  //是否可以播放
  songReady:boolean = false;

  //音量
  volume:number = 10;

  //是否显示音量面板
  showVolumnPanel:boolean = false;

  //是否显示歌曲列表面板
  showPanel:boolean = false;

  // 是否绑定 document click 事件
  bindFlag = false;

  private winClick!: Subscription;

  //当前播放模式
  currentMode!:PlayMode;
  //保存点击改变模式的次数
  modeCount:number = 0;

  @ViewChild('audio', { static: true }) private audio!: ElementRef;
  @ViewChild(NzTooltipDirective, { static: false }) dirRef?: NzTooltipDirective;
  @ViewChild(WyPlayerPanelComponent, { static: false }) private playerPanel!: WyPlayerPanelComponent;

  private audioEl!: HTMLAudioElement;
  constructor(
    private store$: Store<AppStoreModule>,
    @Inject(DOCUMENT) private doc: Document,
    private nzModalServe: NzModalService,
    private batchActionsServe: BatchActionsService,
    private router: Router,
  ) {
    const appStore$ = this.store$.pipe(select(getPlayer));
    const stateArr = [
      {
        type: getSongList,
        cb: (list:Song[]) => this.watchlist(list,'songList')
      },
      {
        type: getPlayList,
        cb: (list:Song[]) => this.watchlist(list,'playList')
      },
      {
        type: getCurrentIndex,
        cb: (index:number) => this.watchCurrentIndex(index)
      },
      {
        type: getPlayMode,
        cb: (mode:PlayMode) => this.watchPlayMode(mode)
      },
      {
        type: getCurrentSong,
        cb: (song:Song) => this.watchCurrentSong(song)
      },
      {
        type: getCurrentAction,
        cb: (action: CurrentActions) => this.watchCurrentAction(action)
      },

    ]
    stateArr.forEach((item:any)=>{
      appStore$.pipe(select(item.type)).subscribe(item.cb)
    })
  }

  ngOnInit(): void {
    this.audioEl = this.audio.nativeElement
    this.audioEl.volume = this.volume / 100
  }

  private watchlist(list: Song[],type:string){
    this[type] = list
  }

  private watchCurrentIndex(index: number){
    this.currentIndex = index
  }

  private watchCurrentAction(action: CurrentActions){
    // controlTooltip
    const title = TipTitles[CurrentActions[action]]
    if(title){
      this.controlTooltip.title = title;
      if(this.showPlayer === 'hide'){
        this.togglePlayer('show')
      }else{
        this.showToolTip()
      }
    }
    this.store$.dispatch(SetCurrentAction({ currentAction: CurrentActions.Other }));
  }
  onAnimateDone(event: AnimationEvent){
    this.animating = false
    if(event.toState === 'show' && this.controlTooltip.title){
      this.showToolTip()
    }
  }

  private showToolTip () {
    console.log(this.dirRef)
    // console.log(this.tooltipBtn.nativeElement      )
    // this.tooltipBtn.nativeElement.show()
    this.dirRef?.show()
    timer(1500).subscribe(()=>{
      this.controlTooltip ={
        title: '',
        show: false
      };
      this.dirRef?.hide()
    })
    this.controlTooltip.show = true
  }

  private watchPlayMode(mode: PlayMode){
    this.currentMode = mode
    if(this.songList){
      let list = this.songList.slice();
      if(mode.type === 'random'){
        list = shuffle(this.songList)
      }
      this.upDateCurrentIndex(list,this.currentSong);
      this.store$.dispatch(SetPlayList({ playList: list}));
  }
    }

  private watchCurrentSong(song: Song){
    this.currentSong = song
    if(song){
      this.duration = song.dt / 1000
    }
  }
  private upDateCurrentIndex(list: Song[], song:Song){
    // const newIndex = list.findIndex(item => item.id === song.id);
    const newIndex = findIndex(list,song);
    this.store$.dispatch(SetCurrentIndex({ currentIndex: newIndex}));
  }

  //播放错误
  onError(){
    this.playing = false;
    this.bufferPercent = 0;
    this.duration = 0
  }

  // 改变播放模式
  changeMode () {
    this.store$.dispatch(SetPlayMode({ playMode: momdeTypes[++this.modeCount % 3] }))
  }

  // 滚动条滚动后获得百分比
  onPercentChange(per:any){
    if(this.currentSong){
      const currentTime = this.duration * (per / 100)
      this.audioEl.currentTime = currentTime;
      if(this.playerPanel){
        this.playerPanel.seekLyric(currentTime * 1000)
      }
    }
  }

  //播放/暂停
  onToggle(){
    if(!this.currentSong){
      if(this.playList.length){
        this.upDateIndex(0)
      }
    }else{
      if(this.songReady){
        this.playing = !this.playing;
        if(this.playing){
          this.audioEl.play();
        }else{
          this.audioEl.pause();
        }
      }
    }
  }

  //控制音量
  onVolumeChange(per:number){
    this.audioEl.volume = per / 100
  }

  // 控制音量面板
  toggleVolPanel(){
    this.togglePanel('showVolumnPanel')
  }

  // 控制音量面板
  toggleListPanel(){
    if(this.songList.length){
      this.togglePanel('showPanel')
    }
  }
  //播放上一首歌曲
  onPrev(index:number){
    if(!this.songReady) return;
    if(this.playList.length === 1){
      this.loop()
    }else{
      const newIndex = index < 0 ? this.playList.length - 1 : index;
      this.upDateIndex(newIndex)
    }
  }

  //播放下一首歌曲
  onNext(index:number){
    if(!this.songReady) return;
    if(this.playList.length === 1){
      this.loop()
    }else{
      const newIndex = index >= this.playList.length ? 0 : index;
      this.upDateIndex(newIndex)
    }
  }

  onCanplay(){
    this.songReady = true
    this.play()
  }

  // 播放歌曲回调
  onTimeUpdate(e:Event){
    this.currentTime = (<HTMLAudioElement>e.target).currentTime
    this.percent = (this.currentTime / this.duration) * 100
    const buffered = this.audioEl.buffered; // 获得缓冲时间
    if(buffered.length && this.bufferPercent < 100){
      this.bufferPercent = (buffered.end(0) / this.duration) * 100;
    }
  }

  // 监听歌曲结束
  onEnded() {
    this.playing = false
    if(this.currentMode.type === 'singleLoop'){
      this.loop()
    }else{
      this.onNext(this.currentIndex + 1)
    }
  }

  // 单曲循环
  private loop(){
    this.audioEl.currentTime = 0;
    this.play()
    if(this.playerPanel){
      this.playerPanel.seekLyric(0)
    }
  }

  private upDateIndex(index:number){
    this.store$.dispatch(SetCurrentIndex({ currentIndex: index }));
    this.bufferPercent = 0
    this.songReady = false
  }

  // 播放
  private play(){
    this.audioEl.play()
    this.playing = true
  }

  // 点击播放器外部回调
  onClickOutSide(target: HTMLElement){
    if(target.dataset.act !== 'delete'){
      this.showVolumnPanel = false
      this.showPanel = false
      this.bindFlag = false
    }
  }

  togglePanel(type:string){
    this[type] = !this[type]
    this.bindFlag = (this.showVolumnPanel || this.showPanel)
  }



  get picUrl():string{
    return this.currentSong ? this.currentSong.al.picUrl:"//s4.music.126.net/style/web2/img/default/default_album.jpg"
  }

  // 改变播放歌曲
  onChangeSong(song:Song){
    this.upDateCurrentIndex(this.playList, song)
  }

  // 删除歌曲
  onDeletSong(song: Song){
    this.batchActionsServe.deletSong(song)
  }
  //清空歌曲
  onClearSong(){
    this.nzModalServe.confirm({
      nzTitle: '确认清空列表？',
      nzOnOk:()=>{
        this.batchActionsServe.clearSong()
      }
    })
  }
  //跳转
  toInfo(path:[string, Number]){
    if(path[1]){
      this.showVolumnPanel = false;
      this.showPanel = false;
      this.router.navigate(path);
    }
  }

  togglePlayer(type: string){
    if(!this.isLocked && !this.animating){
      this.showPlayer = type
    }
  }
}
